package com.leyou.trade.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leyou.auth.local.UserContext;
import com.leyou.common.exceptions.LyException;
import com.leyou.item.client.ItemClient;
import com.leyou.item.dto.SkuDTO;
import com.leyou.trade.dto.OrderFormDTO;
import com.leyou.trade.entity.Order;
import com.leyou.trade.entity.OrderDetail;
import com.leyou.trade.entity.OrderLogistics;
import com.leyou.trade.enums.OrderStatus;
import com.leyou.trade.mapper.OrderMapper;
import com.leyou.trade.service.OrderDetailService;
import com.leyou.trade.service.OrderLogisticsService;
import com.leyou.trade.service.OrderService;
import com.leyou.user.client.UserClient;
import com.leyou.user.dto.AddressDTO;
import feign.FeignException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author 虎哥
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    @Autowired
    private ItemClient itemClient;

    @Autowired
    private OrderDetailService detailService;

    @Autowired
    private OrderLogisticsService logisticsService;

    @Autowired
    private UserClient userClient;

    @Override
    @Transactional  //添加事务
    public Long createOrder(OrderFormDTO orderFormDTO) {
//        1.订单
        //new一个order
        Order order = new Order();
        //  1.1用户块，从上下文中获取用户id
        Long userId = UserContext.getUser().getId();
        order.setUserId(userId);
        //  1.2金额块，获取商品id
        Map<Long, Integer> carts = orderFormDTO.getCarts();
        //      获取商品信息
        Set<Long> skuIds = carts.keySet();   //获取skuId
        List<SkuDTO> skuDTOS = itemClient.querySkuByIds(skuIds);
        //      初始化一个total
        long total = 0;
        //      遍历集合
        for (SkuDTO skuDTO : skuDTOS) {
            //判断商品是否下架
            if (!skuDTO.getSaleable()) {
                //下架了，抛已下架
                throw new LyException(500, "商品已经下架咯！");
            }
            //获取对应商品的数量
            Integer num = carts.get(skuDTO.getId());
            //叠加获取总金额
            total += skuDTO.getPrice() * num;
        }
        //给订单的金额块赋值
        order.setTotalFee(total);
        order.setPostFee(0L);           //邮费暂直接给个0
        order.setActualFee(order.getTotalFee() + order.getPostFee());       //后期需计算优惠或者折扣的钱
        //  1.3 支付方式
        order.setPaymentType(orderFormDTO.getPaymentType());
        //  1.4 状态，从枚举中取
        order.setStatus(OrderStatus.INIT.getValue());
        //添加到数据库中
        boolean save = save(order);
        //判断添加是否成功
        if (!save) {
            //添加失败
            throw new LyException(500, "下单出错啦！");
        }

//        2.订单详情
        //  2.1 回显订单id
        Long orderId = order.getOrderId();
        //  2.2 new一个新的集合
        List<OrderDetail> orderDetailList = new ArrayList<>(skuDTOS.size());
        //  2.3 遍历sku集合
        for (SkuDTO skuDTO : skuDTOS) {
            //获取对应商品的数量
            Integer num = carts.get(skuDTO.getId());
            //调用方法转换为detail
            OrderDetail detail = transferSkuToDetail(skuDTO, num, orderId);
            //添加到集合中
            orderDetailList.add(detail);
        }
        //  2.4  添加到数据库中
        detailService.saveBatch(orderDetailList);

//        3.订单物流
        //  3.1获取addressId
        Long addressId = orderFormDTO.getAddressId();
        AddressDTO addressDTO = null;
        try {
            //  3.2根据id查询address信息
            addressDTO = userClient.queryAddressById(addressId);
        } catch (FeignException e) {
            throw new LyException(e.status(),e.contentUTF8());
        }
        //  3.3判断addressDto中id和userId是否相同
        if (!userId.equals(addressDTO.getUserId())) {
            //不相同，参数有误
            throw new LyException(400, "请求参数有误哦！");
        }
        //  3.4转换为OrderLogistics
        OrderLogistics orderLogistics = addressDTO.toEntity(OrderLogistics.class);
        //   赋值orderId
        orderLogistics.setOrderId(orderId);
        //  3.5添加到数据库
        save = logisticsService.save(orderLogistics);
        //  判断是否成功
        if (!save) {
            throw new LyException(500, "下单出错啦！");
        }
        try {
            //4.减库存
            itemClient.deductStock(carts);
        } catch (FeignException e) {
            throw new LyException(e.status(),e.contentUTF8());
        }
        //返回订单id
        return orderId;
    }

    private OrderDetail transferSkuToDetail(SkuDTO skuDTO, Integer num, Long orderId) {
        //new一个OrderDetail对象
        OrderDetail detail = new OrderDetail();
        //赋值
        detail.setTitle(skuDTO.getTitle());
        detail.setSpec(skuDTO.getSpecialSpec());
        detail.setSkuId(skuDTO.getId());
        detail.setPrice(skuDTO.getPrice());
        detail.setOrderId(orderId);
        detail.setNum(num);
        detail.setImage(StringUtils.substringBefore(skuDTO.getImages(),","));
        //返回
        return detail;
    }
}